#include "pch.h"
#include "ComTools.h"
#include <comdef.h>
#include <Shlwapi.h> 
#include <sstream>

#include "Poco/JSON/Parser.h"
#include "Poco/JSON/ParseHandler.h"
#include "Poco/JSON/JSONException.h"
#include "Poco/StreamCopier.h"
#include "Poco/Dynamic/Var.h"
#include "Poco/JSON/Query.h"
#include "Poco/JSON/PrintHandler.h"

#include "ResultError.h"

using namespace Poco::Dynamic;
using namespace Poco;

#ifdef _WIN32

using namespace std;

std::string ws2s(const wchar_t* ws) {
	_bstr_t t = ws;
	char* pchar = (char*)t;
	std::string result = pchar;
	return result;
}

std::string ws2s(const std::wstring& ws) {
	_bstr_t t = ws.c_str();
	char* pchar = (char*)t;
	std::string result = pchar;
	return result;
}

std::wstring s2ws(const std::string& s) {
	_bstr_t t = s.c_str();
	wchar_t* pwchar = (wchar_t*)t;
	std::wstring result = pwchar;
	return result;
}

std::wstring s2ws(const char* s) {
	_bstr_t t = s;
	wchar_t* pwchar = (wchar_t*)t;
	std::wstring result = pwchar;
	return result;
}

string getCurAppRunPath() {
	string curAppRunPath;
	TCHAR appPath[MAX_PATH] = { 0 };
	DWORD dwStrlen = 0;

	dwStrlen = ::GetModuleFileName(NULL, appPath, MAX_PATH);
	if (dwStrlen > 0) {
		PathRemoveFileSpec(appPath);
#if UNICODE
		curAppRunPath = ws2s(appPath);
#else
		curAppRunPath = appPath;
#endif
	}
	return curAppRunPath;
}

string getCurAppFullPath() {
	string curRunAppPath;
	TCHAR appPath[MAX_PATH] = { 0 };
	DWORD dwStrlen = 0;

	dwStrlen = ::GetModuleFileName(NULL, appPath, MAX_PATH);
	if (dwStrlen > 0) {
#if UNICODE
		curRunAppPath = ws2s(appPath);
#else
		curRunAppPath = appPath;
#endif
	}

	return curRunAppPath;
}

string getCurRunAppName() {
	string curRunAppName;
	TCHAR appName[MAX_PATH] = { 0 };
	DWORD dwStrlen = 0;

	dwStrlen = ::GetModuleFileName(NULL, appName, MAX_PATH);
	if (dwStrlen > 0) {
		PathStripPath(appName);
#if UNICODE
		curRunAppName = ws2s(appName);
#else
		curRunAppName = appName;
#endif
	}

	return curRunAppName;
}

std::string GetExeFileVersion(wstring lpszFileName) {
	string  strVersion;

	wchar_t  szSrcfn[MAX_PATH];
	lstrcpy(szSrcfn, lpszFileName.c_str());


	DWORD  dwVerHnd = 0;
	DWORD  dwVerInfoSize = ::GetFileVersionInfoSizeW(szSrcfn, &dwVerHnd);
	if (dwVerInfoSize) {

		HANDLE    hMem;
		LPVOID    lpvMem;
		unsigned  int  uInfoSize = 0;
		VS_FIXEDFILEINFO  *  pFileInfo;

		hMem = ::GlobalAlloc(GMEM_MOVEABLE, dwVerInfoSize);
		lpvMem = ::GlobalLock(hMem);
		::GetFileVersionInfo(szSrcfn, dwVerHnd, dwVerInfoSize, lpvMem);
		::VerQueryValue(lpvMem, (LPTSTR)L"\\", (void**)&pFileInfo, &uInfoSize);

		WORD  nVer[4];
		nVer[0] = HIWORD(pFileInfo->dwProductVersionMS);
		nVer[1] = LOWORD(pFileInfo->dwProductVersionMS);
		nVer[2] = HIWORD(pFileInfo->dwProductVersionLS);
		nVer[3] = LOWORD(pFileInfo->dwProductVersionLS);
		char VersionBuf[512] = { 0 };
		sprintf_s(VersionBuf, ("%d.%d.%d.%d"), nVer[0], nVer[1], nVer[2], nVer[3]);

		::GlobalUnlock(hMem);
		::GlobalFree(hMem);
		strVersion = VersionBuf;

	}
	return strVersion;
}

std::string strToHex(std::string str, std::string separator) {
	const std::string hex = "0123456789ABCDEF";
	std::stringstream ss;

	for (std::string::size_type i = 0; i < str.size(); ++i)
		ss << hex[(unsigned char)str[i] >> 4] << hex[(unsigned char)str[i] & 0xf] << separator;

	return ss.str();
}

bool GetItemFromJson(std::string strJson, std::string item, std::string &result) {
	JSON::Parser parser;
	Dynamic::Var var;
	parser.reset();
	try {
		var = parser.parse(strJson);
		JSON::Object::Ptr pObj = var.extract<JSON::Object::Ptr>();
		Dynamic::Var ret = pObj->get(item);
		if (ret.isEmpty()) {
			result = "YzqNoniceManage: get json item error :" + item;
			return false;
		}
		else {
			result = ret.toString();
			return true;
		}
	}
	catch (const Poco::Exception & exc) {
		result = "YzqNoniceManage: get json item error :" + std::string(exc.what());
	}
	return false;
}

bool JsonConvertMap(std::string strJson, std::map<std::string, std::string> &jMap, std::string &result) {
	JSON::Parser parser;
	Dynamic::Var var;
	parser.reset();
	try {
		var = parser.parse(strJson);
		JSON::Object::Ptr pObj = var.extract<JSON::Object::Ptr>();
		for (Poco::JSON::Object::ConstIterator itr = pObj->begin(), end = pObj->end(); itr != end; ++itr) {
			jMap[itr->first] = itr->second.toString();
		}
		return true;
	}
	catch (const Poco::Exception & exc) {
		result = "YzqNoniceManage: get json item error :" + std::string(exc.what());
	}
	return false;
}

const std::string getCurrentSystemTime() {
	SYSTEMTIME sys;
	GetLocalTime(&sys);
	char date[60] = { 0 };
	sprintf_s(date, "%4d-%02d-%02d",
		sys.wYear, sys.wMonth, sys.wDay);
	return std::string(date);
}

std::string getLogTimeName(std::string logName) {
	return logName + "-" + getCurrentSystemTime() + ".log";
}

wstring getComputerName() {
	DWORD size = 0;
	wstring wstr;
	GetComputerName(NULL, &size);
	wchar_t *name = new wchar_t[size];
	if (GetComputerName(name, &size)) {
		wstr = name;
	}
	delete[] name;
	return wstr;
}

#endif